﻿

using IotClientService;
using IotClientService.Extensions;
using IotClientService.Models.Lg.Remote;
using IotContract.Dtos.Remotes.Request;
using IotContract.Dtos.Remotes.Response;
using IotContract.Dtos.Servers.Process;
using IotContract.Dtos.Servers.Process.F29;
using IotContract.Enums;
using IotContract.Extensions;
using IotContract.Interfaces;
using IotContract.Interfaces.Process;
using IotContract.Models.Clients.Hks;
using IotContract.Models.Jobs.F29;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive;
using System.Text;
using System.Threading.Tasks;
using XT.Common.Extensions;
using XT.Common.Models.Server;
using XT.Common.Services;

namespace IotServerService.Services.Remotes;
public class ProcessMockApiHandleService : ApiConfigService, IProcessApiHandle
{
    private readonly ILogService _logService;
    private DbService _dbService;
    private string _apiHead = "api";
    public ProcessMockApiHandleService(IHttpClientFactory httpClientFactory,IConnectDataService connectDataService,ILogService logService, DbService dbService) : base(httpClientFactory)
    {
        RemoteApiUrl = connectDataService.AddressConfig.ApiUrl;
        _logService=logService;
        _dbService = dbService;
    }

    

    /// <summary>
    /// 站台提交扫码
    /// </summary>
    /// <param name="unitGroup"></param>
    /// <returns></returns>
    public async Task<AdminCodeResult<F29EnterJob>> CommitEnterTrays(FmsCommitTrayRequest unitGroup)
    {
        FmsEnterTransferRequest request = new FmsEnterTransferRequest
        {
            Cvs = new List<FmsCv>()
           
        };
        if (unitGroup.TagNumber > 0)
        {
            request.Cvs.Add(new FmsCv
            {
                ConveyorCode = unitGroup.TagNumber.ToString(),
                Trays = unitGroup.Trays,
                ForkType = 1,
                TaskNumber = unitGroup.TaskNo
            });
        }

        if (unitGroup.TagNumber2 > 0)
        {
            request.Cvs.Add(new FmsCv
            {
                ConveyorCode = unitGroup.TagNumber2.ToString(),
                Trays = unitGroup.Trays2,
                ForkType = 2,
                TaskNumber = unitGroup.TaskNo
            });
        }
        var unit = request.Cvs.FirstOrDefault();
        await _logService.LogContent($"enter tag begin commit tray,tagNumber {unit.ConveyorCode},tray {unit.Trays.FirstOrDefault()}", XT.Common.Enums.LogEnum.Info, unit.ConveyorCode.ToString(),IotEquipType.CV.ToString());
        var client = CreateHttpClient();
        string url = $"{_apiHead}/tray/inbound?";
        var result = await client.PostFmsData<FmsEnterScResponse>(url, request);

        if (result.Success)
        {
            await _logService.LogContent($"enter tag commit tray success,equipNum {result.Result.StackerCode},taskId {result.Result.TaskNumberId}", XT.Common.Enums.LogEnum.Info, unit.ConveyorCode.ToString(),IotEquipType.CV.ToString());
            var fms = new F29EnterJob
            {
                EquipNum = result.Result.StackerCode,
                FromTagNumber = result.Result.FromTagNumber.To<int>(),
                JobID = result.Result.TaskNumberId,
                FromX=result.Result.FromR,
                FromY=result.Result.FromC,
                FromZ=result.Result.FromF,
                ToX=result.Result.ToR,
                ToY=result.Result.ToC,
                ToZ=result.Result.ToF,
                FromTagNumber2=result.Result.FromTagNumber2,
                FromX2=result.Result.FromR2,
                FromY2=result.Result.FromC2,
                FromZ2= result.Result.FromF2,
                ToX2= result.Result.ToR2,
                ToY2 = result.Result.ToC2,
                ToZ2= result.Result.ToF2,    
                UsePoke=result.Result.UsePoke,
                JobID2= result.Result.TaskNumberId2,
                Num=result.Result.StackerCode,
                Tray=result.Result.Tray,
                Tray2=result.Result.Tray2,
                RightTray=result.Result.rTray,
                RightTray2=result.Result.rTray2
                
            };
            return new AdminCodeResult<F29EnterJob>
            {
                Success = true,
                Result = fms
            };

        }
        else
        {
            
            await _logService.LogContent($"Error enter tag commit tray,tagNumber {unit.ConveyorCode},tray {unit.Trays.FirstOrDefault()},msg {result.Message}", XT.Common.Enums.LogEnum.Error, unit.ConveyorCode.ToString(),IotEquipType.CV.ToString(),true);
            return new AdminCodeResult<F29EnterJob>
            {
                Message = result.Message
            };
        }
    }
    /// <summary>
    /// 开始叠盘通知
    /// </summary>b
    /// <param name="tagNumber"></param>
    /// <returns></returns>
    public async Task<AdminCodeResult<string>> CommitStackOver(int tagNumber)
    {
        await _logService.LogContent($"begin commit stack over,tagNumber {tagNumber}", XT.Common.Enums.LogEnum.Info, tagNumber.ToString(),IotEquipType.CV.ToString());

        var client = CreateHttpClient();
        string url = $"{_apiHead}/tray/stack/notify/{tagNumber}?";
        var result = await client.GetFmsData<string>(url,null);

        if (result.Success)
        {
            return new AdminCodeResult<string> { Success = true };
        }
        else
        {
            await _logService.LogContent($"Error commit stack over,tagNumber {tagNumber}", XT.Common.Enums.LogEnum.Error, tagNumber.ToString(), IotEquipType.CV.ToString(),true);

            return new AdminCodeResult<string> { Message = result.Message };
        }
    }
    /// <summary 
    /// 提交托盘
    /// </summary>
    /// <param name="unit"></param>
    /// <returns></returns>
    public async Task<AdminCodeResult<CvTrayTask>> CommitTrays(FmsCommitTrayRequest unit)
    {
        await _logService.LogContent($"begin commit tray,tagNumber {unit.TagNumber},taskNo {unit.TaskNo},tray {unit.Trays.FirstOrDefault()}", XT.Common.Enums.LogEnum.Info, unit.TagNumber.ToString(), IotEquipType.CV.ToString());
        var client = CreateHttpClient();
        string url = $"{_apiHead}/tray/transfer?";
        var result = await client.PostFmsData<FmsTransferResponse>(url, new FmsTransferRequest
        {
            ConveyorCode = unit.TagNumber.ToString(),
            TaskNo = unit.TaskNo,
            Trays = unit.Trays
        });

        if (result.Success)
        {
            await _logService.LogContent($"commit tray success,tagNumber {unit.TagNumber},taskNo {unit.TaskNo},tray {unit.Trays.FirstOrDefault()}, returnTask {result.Result.TaskNumber},returnDest {result.Result.DesCvCode}", XT.Common.Enums.LogEnum.Info, unit.TagNumber.ToString(),IotEquipType.CV.ToString());
            var fms = new CvTrayTask
            {
                Dest = result.Result.DesCvCode,
                TagNumber = result.Result.OriCvCode,
                TaskNum = result.Result.TaskNumber,
                TrayType = result.Result.StackType
            };
            return new AdminCodeResult<CvTrayTask>
            {
                Success = true,
                Result = fms
            };
            
        }
        else
        {
           
            await _logService.LogContent($"Error commit tray ,tagNumber {unit.TagNumber},taskNo {unit.TaskNo},msg {result.Message}", XT.Common.Enums.LogEnum.Error, unit.TagNumber.ToString(),IotEquipType.CV.ToString(),true);
            return new AdminCodeResult<CvTrayTask>
            {
                Message=result.Message
            };
        }
    }
    /// <summary>
    /// 完成job
    /// </summary>
    /// <param name="jobId"></param>
    /// <param name="jobId2"></param>
    /// <returns></returns>
    public async Task<AdminCodeResult<string>> CompleteJob(string jobId, string jobId2)
    {

        await _logService.LogContent($"Begin CompleteJob,jobid {jobId} jobid2 {jobId2}", XT.Common.Enums.LogEnum.Info, jobId, IotEquipType.STACKER.ToString());

        var client = CreateHttpClient();
        string url = $"{_apiHead}/tray/task/notify";
        var result = await client.PostFmsData<string>(url, new FmsJobCompleteRequest { TaskNumberId=jobId,TaskNumberId2=jobId2});

        if (!result.Success)
        {
            await _logService.LogContent($"Error CompleteJob,jobid {jobId} jobid2 {jobId2}", XT.Common.Enums.LogEnum.Error, jobId, IotEquipType.STACKER.ToString(),true);

        }
        return result;
    }

  
    /// <summary>
    /// 获取入库站台数据
    /// </summary>
    /// <returns></returns>
    public async Task<AdminCodeResult<List<EnterTagGroupDto>>> GetEnterTags()
    {
        var enterResult = await new Func<Task<List<EnterTagGroupDto>>>(() => _dbService.GetEnterTags()).ProtectFunc();
        var admin = new AdminCodeResult<List<EnterTagGroupDto>>();
        if (enterResult.Item2.IsNotNullOrEmpty())
        {
            admin.Success = false;
        
          await  _logService.LogContent("Error can not get enter tags " + enterResult.Item2,XT.Common.Enums.LogEnum.Error,"","GetEnterTags",true);
        }
        else
        {
            admin.Success = true;
            admin.Result = enterResult.Item1;
            _logService.Log("get enter tags " + enterResult.Item1?.Count);

        }

        return admin;

    }
    /// <summary>
    /// 获取换盘数据通道
    /// </summary>
    /// <param name="fmsTray"></param>
    /// <returns></returns>
    public async Task<AdminCodeResult<List<FMTCell>>> GetCebChannel(FmsTrayRequest fmsTray)
    {
        await _logService.LogContent($"Begin Get CebChannel,tray {fmsTray.Tray}", XT.Common.Enums.LogEnum.Info, fmsTray.EquipNum, IotEquipType.CEB.ToString());

        var client = CreateHttpClient();
        string url = $"{_apiHead}/change-disc/tray-enter-work";
        var result = await client.PostFmsData<List<FMTCell>>(url, fmsTray);

        if (!result.Success)
        {
            await _logService.LogContent($"Error Get CebChannel,tray {fmsTray.Tray},{result.Message}", XT.Common.Enums.LogEnum.Error, fmsTray.EquipNum, IotEquipType.CEB.ToString(), true);
        }
        return result;
    }

    /// <summary>
    /// 换盘结束通知
    /// </summary>
    /// <param name="fmsTray"></param>
    /// <returns></returns>
    public async Task<AdminCodeResult<string>> CebWorkDoneInform(FmsTrayRequest fmsTray)
    {
        await _logService.LogContent($"Begin Ceb Done,tray {fmsTray.Tray},Empty {fmsTray.EmptyTray}", XT.Common.Enums.LogEnum.Info, fmsTray.EquipNum, IotEquipType.CEB.ToString());

        var client = CreateHttpClient();
        string url = $"{_apiHead}/change-disc/tray-out-inform";
        var result = await client.PostFmsData<string>(url, fmsTray);

        if (!result.Success)
        {
            await _logService.LogContent($"Error Ceb Done,tray {fmsTray.Tray},Empty {fmsTray.EmptyTray},{result.Message}", XT.Common.Enums.LogEnum.Error, fmsTray.EquipNum, IotEquipType.CEB.ToString(), true);
        }

        return result;
    }
    /// <summary>
    /// 验证
    /// </summary>
    /// <param name="fmsTray"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public async Task<AdminCodeResult<string>> ValidateCebEnterTray(FmsTrayRequest fmsTray)
    {
        await _logService.LogContent($"Begin Ceb Enter,tray {fmsTray.Tray},Empty {fmsTray.EmptyTray}", XT.Common.Enums.LogEnum.Info, fmsTray.EquipNum, IotEquipType.CEB.ToString());

        var client = CreateHttpClient();
        string url = $"{_apiHead}/change-disc/commit-tray-enter";
        var result = await client.PostFmsData<string>(url, fmsTray);

        if (!result.Success)
        {
            await _logService.LogContent($"Error Ceb Enter,tray {fmsTray.Tray},Empty {fmsTray.EmptyTray},{result.Message}", XT.Common.Enums.LogEnum.Error, fmsTray.EquipNum, IotEquipType.CEB.ToString(), true);
        }
        return result;
    }

    public async Task<AdminCodeResult<string>> ValidateCebOutTray(FmsTrayRequest fmsTray)
    {
        await _logService.LogContent($"Begin Ceb Out,tray {fmsTray.Tray},Empty {fmsTray.EmptyTray}", XT.Common.Enums.LogEnum.Info, fmsTray.EquipNum, IotEquipType.CEB.ToString());

        var client = CreateHttpClient();
        string url = $"{_apiHead}/change-disc/commit-tray-leave";
        var result = await client.PostFmsData<string>(url, fmsTray);

        if (!result.Success)
        {
            await _logService.LogContent($"Error Ceb Out,tray {fmsTray.Tray},Empty {fmsTray.EmptyTray},{result.Message}", XT.Common.Enums.LogEnum.Error, fmsTray.EquipNum, IotEquipType.CEB.ToString(), true);
        }

        return result;
    }

    /// <summary>
    /// 验证托盘进入
    /// </summary>
    /// <param name="lgTrayEnter"></param>
    /// <returns></returns>
    public async Task<AdminCodeResult<string>> ValidateEnterTray(string equipNum, IotEquipType equipType, string tray)
    {
        LgTrayEnterRequest lgTrayEnter = new LgTrayEnterRequest
        {
            Tray = tray,
            EquipNum = equipNum,
            EquipType = equipType
        };
        await _logService.LogContent($"Begin Tray Enter,tray {lgTrayEnter.Tray}", XT.Common.Enums.LogEnum.Info, lgTrayEnter.EquipNum, lgTrayEnter.EquipType.ToString());

        var client = CreateHttpClient();
        string url = $"{_apiHead}/common/skip-record-start";
        var result = await client.PostFmsData<string>(url, new FmsTrayRequest { EquipNum = lgTrayEnter.EquipNum, Tray = lgTrayEnter.Tray });
        if (!result.Success)
        {
            await _logService.LogContent($"Error Tray Enter,tray {lgTrayEnter.Tray}", XT.Common.Enums.LogEnum.Error, lgTrayEnter.EquipNum, lgTrayEnter.EquipType.ToString(),true);

        }
        return result;
    }

    /// <summary>
    /// 验证托盘出去
    /// </summary>
    /// <param name="lgTrayEnter"></param>
    /// <param name="tray"></param>
    /// <returns></returns>
    public async Task<AdminCodeResult<string>> ValidateOutTray(string equipNum, IotEquipType equipType, string tray)
    {
        LgTrayOutRequest lgTrayEnter = new LgTrayOutRequest
        {
            Tray = tray,
            EquipNum = equipNum,
            EquipType = equipType
        };
        await _logService.LogContent($"Begin Tray Out,tray {lgTrayEnter.Tray}", XT.Common.Enums.LogEnum.Info, lgTrayEnter.EquipNum, lgTrayEnter.EquipType.ToString());

        var client = CreateHttpClient();
        string url = $"{_apiHead}/common/skip-record-end";
        var result = await client.PostFmsData<string>(url,  new FmsTrayRequest { EquipNum = lgTrayEnter.EquipNum, Tray = lgTrayEnter.Tray });
        if (!result.Success)
        {
            await _logService.LogContent($"Error Tray Out,tray {lgTrayEnter.Tray}", XT.Common.Enums.LogEnum.Error, lgTrayEnter.EquipNum, lgTrayEnter.EquipType.ToString(), true);

        }
        return result;
    }
}
